package canraid.agent.implementations;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;

import canraid.agent.Cagent;
import canraid.agent.Iagent;
import canraid.config.Properties;
import canraid.debug.Level;
import canraid.debug.Logger;

public class NetworkAgent extends Cagent {
	private final int NAME=canraid.gen.R.id.buttonNetwork;
	private Context context=null;
	
	private Handler[] handlers=null;

	public NetworkAgent(Context context) {
		super(1000);
		this.context=context;
	}
	
	public int getAgentName(){
		return NAME;
	}
	
	protected boolean __setup(){
		ConnectivityManager connMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
		if (networkInfo != null && networkInfo.isConnected()) {
	        handlers = getPoolExternalHandlers();
	        return true;
		}
		return false;
	}
	
	protected boolean __loop(){
		byte[] bufferInput = new byte[0];
        int bytesBufferInput=bufferInput.length;
        HttpURLConnection connection = null;
    	BufferedReader streamIn = null;
    	DataOutputStream  streamOut = null;
	    
        try{
        	int sizeBufferOutput=getQueueLength();
        	
			for(int h=0; h<handlers.length;h++){
	    		handlers[h].obtainMessage(Iagent.SIZE_QUEUE_NTW, sizeBufferOutput).sendToTarget();
	    	}
			
        	URL url = new URL(Properties.URL_NETWORK);
	        connection = (HttpURLConnection) url.openConnection();
	        connection.setReadTimeout(5000 /* milliseconds */);
	        connection.setConnectTimeout(7000 /* milliseconds */);
	        connection.setDoOutput(true);
	        connection.setRequestMethod("POST");
	        connection.connect();
	        
	        streamOut = new DataOutputStream (connection.getOutputStream());
	        
        	//Write to URL
        	if (sizeBufferOutput>0){	
				byte[] data=__getCopyBufferOutput(false);
				String encode="CANRAID="+Uri.encode(new String(data));

				streamOut.write(encode.getBytes());
				streamOut.flush();
				__commitCopyBufferOutput(data.length);
        	}
			
			//Read to URL

			streamIn  = new BufferedReader(new InputStreamReader(connection.getInputStream()));
        	String inputLine;
        	String text="";
            while ((inputLine = streamIn.readLine()) != null) 
                text= text + inputLine;
            
            bufferInput=text.getBytes();
            
	        bytesBufferInput=bufferInput.length;
	        
	        if (bytesBufferInput>0){
		        String decode= Uri.decode(new String(bufferInput));
		        if (!decode.trim().equals("")){
		        	bufferInput= decode.getBytes();
		        
	        		for(int h=0; h<handlers.length;h++){
	        			handlers[h].obtainMessage(Iagent.FROM_NTW, bytesBufferInput, -1, bufferInput).sendToTarget();
	        			Logger.setLog(this,Level.INFO,"__loop(). Sending array_byte len("+bytesBufferInput+") to Handler("+handlers[h].toString()+")");
	        		}
	        	}
	        }
		}
		catch(Exception e){
			Logger.setLog(this,Level.ERROR,"__loop(). Running failed. Error("+e.getMessage()+")");
			return false;
		}finally{
			try {
	        	if (streamIn!=null)
	        		streamIn.close();
	        } 
	        catch (IOException e2) {}
			
			try {
	        	if (streamOut!=null)
	        		streamOut.close();
	        } 
	        catch (IOException e2) {}
			
			if (connection!=null)
				connection.disconnect();
			
			connection=null;
			streamIn=null;
			streamOut=null;
		}
		return true;
	}

	public void close() {
		stopPolling();
		
	}

	protected boolean __implementMyHandler(Message msg) {
		Logger.setLog(this,Level.ASSERT,"__implementMyHandler().");
		
		switch (msg.what) {
        case Iagent.FROM_BT:
        	if (msg.arg1>0){
	        	byte[] data= (byte[]) msg.obj;
	        	Logger.setLog(this,Level.INFO,"__implementMyHandler(). FROM_BT");
	        	pushInQueue(data);
        	}
        	break;
        case Iagent.FROM_TEXT:
        	if (msg.arg1>0){
	        	byte[] data= (byte[]) msg.obj;
	        	Logger.setLog(this,Level.INFO,"__implementMyHandler(). FROM_TEXT");
	        	pushInQueue(data);
        	}
        	break;
        default:
        	return false;
        }
		return true;
	}

}
